package com.example.framework;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import com.example.data.GroupData;

public class GroupHelper extends BaseHelperWithWebDriver{


	private Set<GroupData> groupsCache;

	public GroupHelper(ApplicationManager manager) {
		super(manager);
	}
	public Set<GroupData> getGroupsList() {
		manager.getNavigationHelper().openGroupsPage();
		if (groupsCache == null) {
			buildCache();
		}
		return groupsCache;
	}
	
	private void buildCache() {
		groupsCache = new HashSet<GroupData>();//why do we need this initialization?
		manager.getNavigationHelper().openGroupsPage();
		WebElement form = getFirstForm();
		List<WebElement> groupsCheckboxes = getCheckboxesInFormAtGroupsPage(form);
		for (WebElement checkbox : groupsCheckboxes) {
			GroupData group = getGroupByNumberOfCheckbox(checkbox); 
			groupsCache.add(group);
		}
	}
		
	private WebElement getFirstForm() {
		int positionOfFormInHtml = 1;
		return findElements(By.tagName("form")).get(positionOfFormInHtml);
	}

	public List<WebElement> getCheckboxesInFormAtGroupsPage(WebElement form) {
		return form.findElements(By.name(manager.getProperties("group")));
	}

	public WebElement getCheckboxInFormAtGroupsPage(WebElement form, int number) {
		return form.findElements(By.name(manager.getProperties("group"))).get(number);
	}

	public GroupData getGroupByNumberOfCheckbox(WebElement checkbox) {
		String wholeTitle = checkbox.getAttribute("title");		
		wholeTitle = wholeTitle.replaceAll("\\D*\\((.*)\\)", "$1"); //can we remove wholeTitle =  from here?
		GroupData group = new GroupData().setName(wholeTitle).setId(checkbox.getAttribute("value"));
		return group;
	}

	public GroupData getGroupByNumber(int number) {
		return getGroupByNumberOfCheckbox(getCheckboxInFormAtGroupsPage(getFirstForm(), number));
	}

	protected void openCreateNewGroupPage() {
		click(By.name(manager.getProperties("new")));
	}

	public void returnToGroupsPage() {
		click(By.linkText(manager.getProperties("groupPage")));
	}

	private void fillFieldsOfGroup(GroupData object) {
		type(By.name(manager.getProperties("groupName")), object.name);
		type(By.name(manager.getProperties("groupHeader")), object.header);
		type(By.name(manager.getProperties("groupFooter")), object.footer);
	}

	public void createGroup(GroupData group) {		
		manager.getNavigationHelper().openGroupsPage();
		openCreateNewGroupPage();
		fillFieldsOfGroup(group);
		manager.getNavigationHelper().submitCreation();
		buildCache();
	}

	public GroupData deleteGroupByNumber(int number) {
		manager.getNavigationHelper().openGroupsPage();		
		selectGroupByNumber(number);
		GroupData groupToDelete =  getGroupByNumber(number);
		submitGroupDeletion();
		returnToGroupsPage();
		buildCache();
		return groupToDelete;
	}

	private void submitGroupDeletion() {
		click(By.name(manager.getProperties("delete")));
	}

	private WebElement selectGroupByNumber(int numberOfGroup) {
		WebElement selectedGroupByNumber = getCheckboxInFormAtGroupsPage(getFirstForm(), numberOfGroup); 
		selectedGroupByNumber.click();
		return selectedGroupByNumber;
	}
	
	public GroupData modifyGroup(int numberOfGroup, GroupData group) {
		manager.getNavigationHelper().openGroupsPage();		
		WebElement selectGroupByNumber = selectGroupByNumber(numberOfGroup);
		GroupData groupToModify = getGroupByNumberOfCheckbox(selectGroupByNumber);
		click(By.name(manager.getProperties("edit")));
		fillFieldsOfGroup(group);
		submitGroupEdit();
		returnToGroupsPage();
		buildCache();
		return groupToModify;
	}

	private void submitGroupEdit() {
		click(By.name(manager.getProperties("update")));
	}

}
